package com.qf.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.api.dto.ResetPasswordDTO;
import com.qf.api.entity.SysRoleEntity;
import com.qf.api.entity.SysUserEntity;
import com.qf.api.entity.SysUserRoleEntity;
import com.qf.api.form.UserForm;
import com.qf.api.form.UserProfileForm;
import com.qf.api.service.SysUserRoleService;
import com.qf.api.service.SysUserService;
import com.qf.api.vo.UserPageVO;
import com.qf.core.constant.MethodConstant;
import com.qf.core.constant.MinioConstant;
import com.qf.core.exception.BaseException;
import com.qf.core.response.ResponseCode;
import com.qf.core.utils.FileUtils;
import com.qf.dao.mapper.SysUserMapper;
import com.qf.minio.service.MinioService;
import com.qf.security.SysLoginUser;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: sin
 * @Date: 2025/5/21 21:14
 * @Description:
 **/
@Service
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUserEntity> implements UserDetailsService, SysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Resource
    SysUserRoleService userRoleService;

    @Resource
    PasswordEncoder passwordEncoder;


    @Resource
    private MinioService minioService;

    /**
     * 通过用户名查询用户信息
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 数据库获取信息
        SysLoginUser loginUser = new SysLoginUser();
        SysUserEntity user = this.selectUserByUsername(username);
        // TODO 后期考虑使用断言
        if(user == null) {
            throw new UsernameNotFoundException("用户名不存在");
        }
        loginUser.setUser(user);
        log.info("user:{}",loginUser);
        //将数据库中的角色拆分成SpringSecurity结构
        String roles = user.getRoles().stream().map(SysRoleEntity::getCode).collect(Collectors.joining(","));
        loginUser.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(roles));
        return loginUser;
    }

    @Override
    public SysUserEntity selectUserByUsername(String username) {
        return sysUserMapper.selectByUsername(username);
    }


    @Override
    public List<UserPageVO> getUserPage(String username, String mobile, Integer status) {
        try {
            return sysUserMapper.queryUser(username, mobile, status);
        } catch (Exception e) {
            throw new BaseException(ResponseCode.OPT_ERROR.getCode(), MethodConstant.SELECT + MethodConstant.USER + MethodConstant.ERROR);
        }
    }

    @Override
    public boolean updateUser(UserForm userForm) {
        try {
            SysUserEntity user = sysUserMapper.selectById(userForm.getId());
            if (userForm.getRoleId() != null) {
                userRoleService.updateById(new SysUserRoleEntity(userForm.getId(), userForm.getRoleId()));
            }
            return sysUserMapper.updateById(getUser(user, userForm)) > 0;
        } catch (Exception e) {
            throw new BaseException(ResponseCode.OPT_ERROR.getCode(),
                    userForm.getUsername() + MethodConstant.EDIT + MethodConstant.USER + MethodConstant.ERROR);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveUser(UserForm userForm) {
        SysUserEntity user = sysUserMapper.getUserByUsername(userForm.getUsername());
        if (user != null) {
            throw new BaseException(ResponseCode.ERROR.getCode(), MethodConstant.USER + MethodConstant.EXIST);
        }
        userForm.setPassword(passwordEncoder.encode(userForm.getPassword()));
        user = getUser(new SysUserEntity(), userForm);
        try {
            this.save(user);
            return userRoleService.save(new SysUserRoleEntity(user.getId(), userForm.getRoleId()));
        } catch (Exception e) {
            throw new BaseException(ResponseCode.OPT_ERROR.getCode(),
                    userForm.getUsername() + MethodConstant.ADD + MethodConstant.USER + MethodConstant.ERROR);
        }
    }

    @Override
    public boolean uploadAvatar(MultipartFile avatar, Long userId) {
        if(!FileUtils.isImage(avatar)) {
            throw new BaseException(ResponseCode.UPLOAD_FILE_TYPE_ERROR);
        }
        String url = minioService.uploadFile(avatar, MinioConstant.BUCKET_NAME_AVATAR, FileUtils.generateUniqueFileName(avatar.getOriginalFilename()));
        return sysUserMapper.uploadAvatar(url, userId) > 0;
    }

    @Override
    public boolean resetPassword(ResetPasswordDTO resetPasswordDTO) {
        String encode = passwordEncoder.encode(resetPasswordDTO.getPassword());
        return sysUserMapper.updatePassword(resetPasswordDTO.getId(), encode) > 0;
    }

    @Override
    public SysUserEntity selectUserById(Long id) {
        return sysUserMapper.selectById(id);
    }

    @Override
    public boolean updateCurrentUserPassword(SysUserEntity user, String oldPassword, String newPassword, String confirmPassword) {
        boolean equals = newPassword.equals(confirmPassword) && passwordEncoder.matches(oldPassword, user.getPassword());
        if (!equals) {
            throw new BaseException(ResponseCode.OLD_PASSWORD_ERROR);
        }
        String encode = passwordEncoder.encode(newPassword);
        return sysUserMapper.updatePassword(user.getId(), encode) > 0;
    }

    @Override
    public boolean updateCurrentUserInfo(Long userId, UserProfileForm form) {
        return sysUserMapper.updateCurrentUserInfo(userId, form.getNickname(), form.getMobile(), form.getEmail(), form.getGender()) > 0;
    }

    @Override
    public boolean updateUserStatus(Long id, Integer status) {
        status = status == 1 ?0 :1;
        return sysUserMapper.updateUserStatus(id,status) > 0;
    }

    // 获取用户信息,并设置修改用户或者新增用户
    private SysUserEntity getUser(SysUserEntity user, UserForm userForm) {
        // 修改用户信息，需要修改角色信息
        user.setNickname(userForm.getNickname());
        user.setEmail(userForm.getEmail());
        user.setMobile(userForm.getMobile());
        user.setStatus(userForm.getStatus());
        user.setRemark(userForm.getRemark());
        user.setUsername(userForm.getUsername());
        user.setGender(userForm.getGender());
        user.setPassword(userForm.getPassword());
        return user;
    }
}
